home *** CD-ROM | disk | FTP | other *** search
/ Network Support Library / RoseWare - Network Support Library.iso / apidev / logdis.arc / LOGDISP.C next >
Text File  |  1990-09-06  |  13KB  |  438 lines

  1. /* LOGDISP.C  Novell Utility
  2.    Purpose: Program to Display a File if a certain amount of time has
  3.             passed since the last login.
  4.    Usage - To limit system information/news files to once a day displays
  5.    Input - 1st Parameter is time passed in minutes
  6.            2nd Parameter is file spec of file to be displayed
  7.            3rd Parameter is optional wait time after display
  8.    Output- Will display text file if time duration has passed or file date
  9.            is newer than the last login date.
  10.  
  11.  * Author - Wm Stackpole, Code 114.4, Puget Sound Naval Shipyard
  12.             for the public domain
  13.  * Date   - 08/29/90
  14.  * Written in MSC v5.1 
  15.  * Requires Novell Netware C Interface-DOS
  16.  * Command line: cl /AM logdisp.c /link MNIT.LIB
  17. */
  18.  
  19. /* Portions of this code are the copyrighted property of William Stackpole
  20.    and Precision Data Consultants.  Used with permission.
  21. */ 
  22.  
  23. /* Update Log  */
  24. /* v1.1 Creates LST$LOG.DAT file because LAST_LOGIN property couldn't be used */
  25. /*      Added -n No Update option for LST$LOG.DAT file */
  26.  
  27. /* Notes
  28.    Suggested Parameters
  29.    -cNN        Number of columns for word wrap
  30.    -lNN        Number of lines for pause
  31. */
  32.  
  33. #include <stdio.h>
  34. #include <ctype.h>
  35. #include <dos.h>
  36. #include <string.h>
  37. #include <nit.h>
  38. #include <niterror.h>
  39. #include <time.h>
  40. #include <conio.h>
  41. #include <bios.h>
  42. #include <sys/types.h>
  43. #include <sys/stat.h>
  44.  
  45. #define inc "Puget Sound Naval Shipyard, Wm Stackpole, 1990"
  46. #define prg "LOGDISP"
  47. #define ver "1.1"
  48.  
  49. #define FALSE 0
  50. #define TRUE 1
  51. #define DEBUG FALSE
  52. #define    MAXDUR 32768   /* Maximum duration  3+ weeks */
  53.  
  54. union  REGS        Regs;
  55. struct SREGS       Segs;
  56.  
  57. /* Prototype functions */
  58.  
  59. int     NAttach(void);         /* See if user is attached to Novell network */
  60. void     Help(void);            /* Display help */
  61. long int DateToMinutes(int,int,int,int,int); /*Convert date to minutes */
  62. int     WaitOne(int);        /* Pause with a timeout */
  63. int     IsOption(char*);     /*Test of argv option */
  64. void     ErrExit(int,int);     /*Exit with Error Message */
  65. void     ExitThisPrgm(int);     /*Exit with Error Code */
  66. void     DisplayFile(FILE*,int,int);  /*Display a file with word wrap and page pause */
  67.  
  68. /* Global variables */
  69.  
  70. char *HelpMess[] ={
  71.          "-Display a file if a certain amount of time has passed",
  72.          "since the user's last login.",
  73.          "   Usage: LOGDISP [nnn] [d:][\\path\\]filename.ext [-w[tt]] [-n]",
  74.          "Where nnn is the time to have passed in minutes (Default is 240)",
  75.          "d: is the drive letter or volume name, \\path\\ is the directory",
  76.          "path and filename.ext is the name of the text file, -n prevents",
  77.          "login time update, -w is a program pause of 20 seconds (or key press)",
  78.          "and tt is an optional pause time in seconds (0 = wait for key press).",
  79.          "Returns ERRORLEVEL 1 for fatal errors.",
  80.           inc,
  81.          };
  82. int HelpLen=10;
  83.  
  84. char *ErrorMess[]={
  85.          "Unknown option.",
  86.          "Bad or missing command line parameter.",
  87.      "Invalid time parameter (1-32768).",
  88.           "Opening display file.",
  89.          "Bad or missing file specification.",
  90.          "Opening LST$LOG.DAT file.",
  91.          "Reading LST$LOG.DAT file.",
  92.          "Writing LST$LOG.DAT file.",
  93.           };
  94. int ErrLen=8;
  95.  
  96. int        completionCode;
  97. BYTE        securityAccessLevel;
  98. long        objectID;
  99. char          objectName[48];
  100. WORD          objectType;
  101. char        propertyName[16];
  102. int        segmentNumber=1;
  103. BYTE        propertyValue[128];
  104. BYTE        moreSegments;
  105. BYTE        propertyFlags;
  106.  
  107. main(argc,argv)
  108. int argc;
  109. char *argv[];
  110. {
  111.  
  112.   int        haveDuration=FALSE;
  113.   int        haveFileName=FALSE;
  114.   int        duration=240;
  115.   int        updateLog=TRUE;
  116.   
  117.   long int     currentTime, lastLogTime=0;
  118.   int        i;
  119.   FILE        *fp;
  120.   char        dateAndTime[7];
  121.   char        ans[8];
  122.   static char    fileName[128]="\0";
  123.   static char    filePath[128]="\0";
  124.   char        c;
  125.   struct    stat buf;
  126.   int        fh, result;
  127.   struct    tm *newtime;
  128.   int        waitTime=-1;
  129.   int        pageWidth=-1;
  130.   int        pageLength=-1;
  131.  
  132.   /* Parse the arguments */
  133.   if(argc<2)
  134.     Help();
  135.   for(i=1;i<argc;i++)    /* Scan each arguement for option, duration, file */
  136.   {
  137.     if(IsOption(argv[i]))
  138.     {
  139.       switch(tolower(argv[i][1]))
  140.       {
  141.         case 'w':
  142.                  if(strlen(argv[i])>2){
  143.                    strcpy(dateAndTime,&argv[i][2]);
  144.                    waitTime = atoi(dateAndTime);
  145.                  }
  146.                  else
  147.                    waitTime = 20;  
  148.                  break;
  149.         case 'c':            /* page width in columns */
  150.                  if(strlen(argv[i])>2){
  151.                    strcpy(dateAndTime,&argv[i][2]);
  152.                    pageWidth = atoi(dateAndTime)<15?15:atoi(dateAndTime);
  153.                    pageWidth = pageWidth>132?132:pageWidth;
  154.                  }
  155.                  else
  156.                    pageWidth = 80;  
  157.                  break;
  158.         case 'l':            /* page length option */
  159.                  if(strlen(argv[i])>2){
  160.                    strcpy(dateAndTime,&argv[i][2]);
  161.                    pageLength = atoi(dateAndTime)<8?8:atoi(dateAndTime);
  162.                    pageLength = pageLength>120?120:pageLength; 
  163.                  }
  164.                  else
  165.                    pageLength = 23;  
  166.                  break;
  167.         case 'n':            /* no update of LST$LOG.DAT file */
  168.                  updateLog=FALSE;
  169.                  break;
  170.         default :
  171.                  ErrExit(0,1);
  172.       }
  173.     }
  174.     else                /*  Test for file name parameter */
  175.     {
  176.       if((strchr(argv[i],'\\')!=NULL) || (strchr(argv[i],':')!=NULL) ||
  177.       (strchr(argv[i],'.')!=NULL))
  178.       {                        /* Assume a file spec */
  179.         if(haveFileName)
  180.           ErrExit(1,1);
  181.         else
  182.         {
  183.           strcpy(fileName,argv[i]);
  184.           haveFileName=TRUE;
  185.         }
  186.       }
  187.       else
  188.       {            /* Assume it's a duration parameter */
  189.         if(haveDuration)
  190.           ErrExit(1,1);
  191.         else
  192.         {
  193.           duration=atoi(argv[i]);
  194.           haveDuration=TRUE;
  195.         }
  196.       }
  197.     }
  198. #if DEBUG
  199.   printf("Wait=%i  Duration=%i Filespec=%s \n",waitTime,duration,fileName);
  200. #endif
  201.  
  202.   }
  203.  
  204. /* Test validity of parsed parameters */ 
  205.   if(strlen(fileName)==0)
  206.     ErrExit(4,1);
  207.   if((duration==0) || (duration>MAXDUR)) /* Test for maximum value on timer */
  208.     ErrExit(2,1);
  209.  
  210.   i=NAttach();                    /* See if we're attached to Network */
  211.  
  212.   if(i!=0)
  213.   {                /* Exit with error if not attached */
  214.     printf("%s v%s  %s\nThis utility requires Advance Netware to run.\n",
  215.             prg,ver,inc);
  216.     ExitThisPrgm(1);
  217.   }
  218.   /* Convert object ID and put in file specification string */
  219.   sprintf(filePath,"SYS:MAIL\\%lX\\LST$LOG.DAT\0",objectID);
  220.   
  221.   GetFileServerDateAndTime(dateAndTime);   /* Get the current date and time */
  222.   currentTime=DateToMinutes(dateAndTime[0]+1900,dateAndTime[1],dateAndTime[2],
  223.               dateAndTime[3],dateAndTime[4]);   /* Convert it to minutes */
  224.  
  225. #if DEBUG
  226.   printf("Current Date %i/%i/%i, %i:%i  Minutes=%li\n",dateAndTime[0],
  227.           dateAndTime[1],dateAndTime[2],dateAndTime[3],dateAndTime[4],
  228.           currentTime);
  229.   printf("File path is %s\n",filePath);
  230. #endif
  231.  
  232. /* Last Login is useless since it is updated prior to login script execution */
  233. /*  We will need to save this info in the user's mailbox */
  234. /*  Filename = LST$LOG.DAT                               */
  235. /*  Contents will be a long Minutes of the last login    */
  236.            
  237.  
  238.   result = stat(filePath,&buf);          /* Get the file date and time */
  239.  
  240. #if DEBUG
  241.   if(result!=0)
  242.      printf("ERROR - Unable to read LST$LOG.DAT file information\n");
  243. #endif
  244.  
  245.   fp = fopen(filePath,"rb");
  246.   if(fp!=NULL){
  247.     completionCode=fread(&lastLogTime,sizeof(long),1,fp);
  248.     if(completionCode==0){
  249.        printf("ERROR - %s\n",ErrorMess[6]);
  250.        lastLogTime=0;
  251.     }
  252.  
  253. #if DEBUG
  254.     if(fp==NULL)
  255.       printf("ERROR - %s\n",ErrorMess[5]);
  256. #endif
  257.  
  258.   }
  259.  
  260.   /* Write current time into file and close */
  261.   if(updateLog){
  262.     fp = fopen(filePath,"wb");
  263.     if(fp==NULL)
  264.        printf("ERROR - %s\n",ErrorMess[5]);
  265.     else{
  266.        completionCode=fwrite(¤tTime,sizeof(long),1,fp);
  267.        if(completionCode==0)
  268.          printf("ERROR - %s\n",ErrorMess[7]);
  269.     }
  270.   }         
  271. #if DEBUG
  272.   printf("Log %li + Duration %i = %li > %li\n",lastLogTime,duration,
  273.             lastLogTime+duration,currentTime);
  274. #endif            
  275.                         
  276.   if((lastLogTime+duration)>currentTime)   /* Test for duration has passed */
  277.   {
  278.     result = stat(fileName,&buf);          /* Get the file date and time */
  279.     if(result!=0)
  280.        printf("ERROR - Unable to read file information\n");
  281.     else{       
  282.        newtime = localtime(&buf.st_atime);
  283.        currentTime = DateToMinutes(newtime->tm_year+1900,newtime->tm_mon+1,
  284.                      newtime->tm_mday,newtime->tm_hour,newtime->tm_min);
  285. #if DEBUG
  286.        printf("File Date %s\n",ctime(&buf.st_atime));
  287.        printf("Log %li < File %li\n",lastLogTime,currentTime);
  288. #endif        
  289.        if(lastLogTime>currentTime)        /* Compare to last login date */
  290.           ExitThisPrgm(0);
  291.     }
  292.   }
  293.  
  294.   /* Display the file */
  295.   fp=fopen(fileName,"r");
  296.   if(fp==NULL)
  297.      ErrExit(3,1);
  298.  
  299.   DisplayFile(fp, pageWidth, pageLength);  
  300.   
  301.   fclose(fp);
  302.   if(waitTime!=-1)
  303.     WaitOne(waitTime);
  304.   ExitThisPrgm(0);
  305. }
  306.  
  307. /* FUNCTION DateToMinutes - Convert a date to minutes since 1980
  308.    Input  - Year, month, day, hour, minute
  309.    Format - YYYY >1970 , MM( 1-12), DD, HH (0-23), MM (0-59)
  310.    Output - long int minutes passed since 1980
  311. */   
  312. long int DateToMinutes(int year,int month,int day,int hour,int minute)
  313. {
  314.   static  int    daysPassed[13]={0,0,31,59,90,120,151,181,212,243,273,304,334};
  315.  
  316.   year -= 1970;
  317.   day += daysPassed[month]-(!(year%4 || month<3)?0:1);
  318.  
  319.   return((long)minute+60*((long)hour+24*((long)day+(year/4)+(year%4?1:0)+
  320.          (long)year*365)));
  321. }
  322.  
  323. /* FUNCTION NAttach - Tests for attachment to network */
  324. /* Output - Errorlevel  0 if shell loaded and user is logged in */
  325. /*          Errorlevel  1 if shell is not loaded */
  326. /*          Errorlevel  2 if shell loaded and user is not logged in */
  327. /*          Errorlevel 99 if user is supervisor */ 
  328. int NAttach(void)
  329. {
  330.      
  331.   completionCode = GetBinderyAccessLevel(&securityAccessLevel,&objectID);
  332.   if (completionCode !=0)   /* Shell Not Loaded */
  333.      return(1);
  334.  
  335.   completionCode = GetBinderyObjectName(objectID,objectName,&objectType);
  336.   if (completionCode != 0)  /* Not logged in */
  337.      return(2);
  338.  
  339.   return(0);
  340. }
  341.  
  342. /* FUNCTION Help - Displays the help message and exits */
  343. void Help(void)
  344. {
  345.   int i;
  346.   printf("\n%s v%s ",prg,ver);
  347.   for(i=0;i<HelpLen;i++)
  348.      puts(HelpMess[i]);
  349.   exit(1);
  350. }
  351.  
  352. /* FUNCTION WaitOne - Waits n seconds before continuing execution
  353.    Input  - Time to wait in seconds (1 to 120)  0=Forever 
  354.    Output - 0 = Time expired  1=User pressed key
  355. */   
  356. int WaitOne(int seconds)
  357. {
  358.    int dflt_time  = 6;
  359.    int dflt_limit = 120;
  360.    long int start_time, cur_time;
  361.    int i=0;
  362.    static char mess1[]="\nPress any key to continue...";
  363.  
  364.    cputs(mess1);
  365.    if(seconds!=0){
  366.       seconds    = seconds<1?dflt_time:seconds;
  367.       seconds    = seconds>dflt_limit?dflt_limit:seconds;
  368.       start_time = time(&start_time)+seconds;
  369.       while(start_time>time(&cur_time))
  370.       {
  371.         if(_bios_keybrd(1)!=0){
  372.           getch();
  373.           i = 1;
  374.           break;
  375.         }
  376.       }
  377.    }
  378.    else{
  379.      i = 1;
  380.      getch();
  381.    }
  382.    putchar('\n');
  383.    return(i);
  384. }
  385.  
  386. /* FUNCTION IsOption - Tests for command line options
  387.    Input  - argv to be tested 
  388.    Output - TRUE or FALSE
  389. */   
  390. int IsOption(char *instring)
  391. {
  392.   return((instring[0]=='/' || instring[0]=='-')?TRUE:FALSE);
  393. }
  394.  
  395. /* FUNCTION ErrExit - Display an Error Message and Exit with Errorlevel
  396.    Input  - Error message number and errorlevel number
  397.    Output - ERRORLEVEL to DOS process
  398. */   
  399. void     ErrExit(int errMessage,int errLevel)
  400. {
  401.   if(errMessage<ErrLen)
  402.     printf("ERROR - %s\n%s v%s  %s\n",ErrorMess[errMessage],
  403.             prg,ver,inc);
  404.   ExitThisPrgm(errLevel);
  405.  
  406. /* FUNCTION ExitThisPrgm - Exit program with Errorlevel
  407.    Input  - Errorlevel 
  408.    Output - ERRORLEVEL to DOS process
  409. */   
  410. void     ExitThisPrgm(int Errorlevel)
  411. {
  412.   exit(Errorlevel);
  413. }
  414.  
  415. /* FUNCTION DisplayFile - Display a file with work wrap and page pause
  416.    Input  - File pointer, page width and page length 
  417.    Output - File to stdout (Returns nothing)
  418. */   
  419. void    DisplayFile(FILE *fp,int width,int length)
  420. {
  421.   char        lineBuffer[255];
  422.   char        ch;
  423.   int        haveWrap = width==-1?FALSE:TRUE;
  424.   int        havePause= length==-1?FALSE:TRUE;
  425.   int        i;
  426.     
  427.   ch = fgetc(fp);
  428.   while(!(feof(fp)))
  429.   {
  430.     /* Read in a line or fill buffer */
  431.     
  432.     ch=fgetc(fp);
  433.     putchar(ch);
  434.   }
  435.   return;
  436. }
  437.